/* En este archivo deben ir los prototipos de funciones, estructuras, etc */

#define MAX_VISIBILIDAD 20
#define MAX_ENTRADAS 200
#define MAX_TEXTO 100

#define COMIENZO 0
#define FINAL    1

#define ERROR_ABRIR_ARCHIVO -1
#define EXITO_ABRIR_ARCHIVO 0


#define CANTIDAD_VARIABLES 5000
#define AUN_SIN_TIPO    -2
#define AUN_SIN_FUNCION -3
#define INICIO_TIPO_FUNCION -4
#define INICIO_TIPO_VPF -5

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "list.h"
#include "sintactico.tab.h"


#define SIMPLE 0
#define VECTOR 1
#define MATRIZ 2

struct id{
    char *lexema;
    int compuesto;
    int tipo;
    struct textoImpresion *buffer;
};

struct variable{
    struct list_head lista;
    struct list_head listaDeclarados;
    char *lexema;
    int     tipo;
    int compuesto;
};

struct variable_por_funcion{
    char nombre[45];
    int tipo;
    int compuesto;
    int funcion; // nombre de la funcion a que pertenece
};


struct argumento{
    struct list_head lista;
    int posicion;
    int tipo;
    char *lexema;
};

struct argumentos{
    struct argumento *args;
    int cArg;    
    struct textoImpresion *buffer;
};

struct funcion{
    struct list_head lista;
    struct argumentos *listaArgumentos;
    char *lexema;
    int retorno;
    int prototipo;
};

struct textoImpresion{
    struct list_head lista;
    char *texto;
};

void imprimirTexto(char *texto);
void imprimirBuffer(struct textoImpresion *listaTexto);
void imprimirPantalla(struct textoImpresion *listaTexto);
struct textoImpresion *agregarTextoAntes(char *texto,struct textoImpresion *listaTexto);
void agregarTextoDespues(char *texto,struct textoImpresion *listaTexto);
void agregarLista(struct textoImpresion *cabeza,struct textoImpresion *resto);
struct id* crearNodoId(void);
int verificaMain(void);
void agregarDeclaracion(struct list_head *nuevo,struct list_head *lista);
void imprimirFuncion(struct funcion *f, int n);
int compararArgumentos(struct argumentos *real, struct argumentos *llamada,char *lexema);
void agregarNodoArgumento(int tipo,char *lexema,struct argumentos *a);
struct argumentos* crearNodoArgumentos(void);
struct funcion* crearNodoFuncion(int retorno, char *lexema, struct argumentos *args);
void agregarNodoFuncion(struct funcion *f);
struct funcion *buscarNodoFuncion(char *s);
struct funcion *buscarNodoFuncionR(char *s);
struct variable* crearNodoVariable(void);
void agregarVariable(struct variable *v);
struct variable *buscaVariableScope(char *s,int scope);
struct variable *buscaVariable(char *s);
void asignarDeclaradosTipo(int tipo,struct list_head *lista);
void incrementarScope(void);
void decrementarScope(void);
void errorFatal(char *msj);
void errorSemantico(char *lexema,char *msj);

/* Funcion que se encuentra en el analizador lexico*/
int cambiar_yyin(FILE *);

